<?php


namespace app\api\controller;

use app\api\model\User as UserModel;
use app\api\controller\Wallet as WalletController;
use app\api\model\Wallet as WalletModel;


/***
 * Class User 用户相关
 * @package app\api\controller
 */
class User extends Base
{

    /***
     * 用户登录
     */
    public function login()
    {
        //检查参数
        $rules = [
            ['code', 'require', '10001'],
            ['nick_name', 'require', '10001'],
            ['avater', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //请求微信服务器
        $url       = config('wx.login_url');
        $wx_params = [
            'appid'      => config('wx.appid'),
            'secret'     => config('wx.appkey'),
            'js_code'    => $this->params['code'],
            'grant_type' => 'authorization_code',
        ];
        $data      = $this->curl_request($url, $wx_params, 'GET', array("Content-type: text/html; charset=utf-8"));
        $result    = json_decode($data, true);
        if (empty($result)) {
            $this->return_msg('50000', '获取seesion_key或openID异常', []);
        } else {
            $errcode = array_key_exists('errcode', $result);
            if ($errcode) {
                $this->return_msg('30000', "获取openid和session_key失败", $result);
            } else {
                //过滤不必要的参数
                $safe_data = $this->getDataByRule($this->params, $rules);
                $arr       = $this->grantToken($result, $safe_data);
                $this->return_msg('00000', '获取成功', $arr);
            }
        }
    }

    /***
     * Desc : 包装获取到的session_key和openid
     * User : HAIYUN
     * Date : 2022-01-04 13:48
     * @param $result
     * @return array
     */
    private function grantToken($result, $safe_data)
    {
        //拿到openid
        $openid = $result['openid'];
        //查看数据库是否存在,存在则不处理，不存在则新增
        $userModel = new UserModel();
        $user      = $userModel->check_exist($openid);
        if ($user) {
            $uid = $user['id'];
        } else {
            $safe_data['openid'] = $openid;
            unset($safe_data['code']);
            //创建新用户
            $user_info = $userModel::create($safe_data);
            $uid       = $user_info['id'];
            //创建钱包
            $walletController = new WalletController();
            $walletController->createWallet($uid);
        }
        //生成令牌,写入缓存
        //key: 令牌
        //value；result,uid
        $cache_value = $this->preparCacheValue($result, $uid);
        $token       = $this->saveToCache($cache_value);
        return [
            'token'     => $token,
            'user_info' => $user ? $user : $user_info,
        ];
    }

    /***
     * Desc :准备缓存数据
     * User : HAIYUN
     * Date : 2022-01-04 14:27
     * @param $result
     * @param $uid
     */
    private function preparCacheValue($result, $uid)
    {
        $cache_value        = $result;
        $cache_value['uid'] = $uid;
        return $cache_value;
    }

    /***
     * Desc :写入缓存
     * User : HAIYUN
     * Date : 2022-01-04 14:31
     * @param $cache_value
     */
    private function saveToCache($cache_value)
    {
        $key      = $this->generateToken();
        $value    = json_encode($cache_value);
        $expre_in = config('setting.token_expre_in');
        $request  = cache($key, $value, $expre_in);
        if (!$request) {
            $this->return_msg('40000', "服务器缓存异常", []);
        }
        return $key;
    }

    /***
     * Desc :生成令牌
     * User : HAIYUN
     * Date : 2022-01-04 15:02
     * @return string
     */
    private function generateToken()
    {
        //生产32位随机字符串
        $randChars = $this->getRandStr(32);
        //加三组字符串，进行md5加密
        $time_stamp = $_SERVER['REQUEST_TIME'];
        //salt 盐
        $salt = config('secure.token_salt');
        return md5($randChars . $time_stamp . $salt);
    }


    /***
     * Desc :用户修改头像
     * User : HAIYUN
     * Date : 2022-01-05 20:26
     */
    public function updateHeadImg()
    {
        //获取用户
        //根据token获取uid
        $uid = $this->getCurrentTokenVar("uid");
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $uid)->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        //校验参数
        $rules = [
            ['avater', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //过滤不必要的参数
        $safe_data = $this->getDataByRule($this->params, $rules);
        //修改头像地址
        $res = $userModel->edit($safe_data, ['id' => $uid]);
        if ($res !== false) {
            $this->return_msg("00000", "修改头像成功", $safe_data);
        } else {
            $this->return_msg("20002", "修改头像失败", []);
        }
    }

    /***
     * Desc :上传用户头像
     * User : HAIYUN
     * Date : 2022-01-05 21:02
     */
    public function uploadHeadImg()
    {
        //上传新头像并裁剪
        $url  = config('setting.avater_img_url');
        $type = 'avater';
        $this->img_upload($url, $type);
    }

    /***
     * Desc :用户修改个人描述
     * User : HAIYUN
     * Date : 2022-01-06 11:23
     */
    public function updateDescribe()
    {
        //获取用户
        //根据token获取uid
        $uid = $this->getCurrentTokenVar("uid");
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $uid)->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        //校验参数
        $rules = [
            ['describe', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //过滤不必要的参数
        $safe_data = $this->getDataByRule($this->params, $rules);
        //修改描述
        $res = $userModel->edit($safe_data, ['id' => $uid]);
        if ($res !== false) {
            $this->return_msg("00000", "修改描述成功", $safe_data);
        } else {
            $this->return_msg("20002", "修改描述失败", []);
        }
    }

    /***
     * Desc :
     * User : HAIYUN
     * Date : 2022-01-06 11:41
     */
    public function updateNickName()
    {
        //获取用户
        //根据token获取uid
        $uid = $this->getCurrentTokenVar("uid");
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $uid)->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        //校验参数
        $rules = [
            ['nick_name', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //过滤不必要的参数
        $safe_data = $this->getDataByRule($this->params, $rules);
        //修改描述
        $res = $userModel->edit($safe_data, ['id' => $uid]);
        if ($res !== false) {
            $this->return_msg("00000", "修改昵称成功", $safe_data);
        } else {
            $this->return_msg("20002", "修改昵称失败", []);
        }
    }

    /***
     * Desc :绑定手机号
     * User : HAIYUN
     * Date : 2022-01-06 16:00
     */
    public function bindPhoneNumber()
    {
        //获取用户
        //根据token获取uid
        $uid = $this->getCurrentTokenVar("uid");
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $uid)->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        //校验参数
        $rules = [
            ['phone_number', 'require|/^1[34578]\d{9}$/', '10001|10002'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //查询手机号是否被占用
        $where      = [
            'phone_number' => $this->params['phone_number'],
            'id'           => ["NEQ", $uid],
        ];
        $phone_info = $userModel->where($where)->find();
        if ($phone_info) {
            $this->return_msg("20005", "该手机号已被占用", []);
        } else {
            //过滤不必要的参数
            $safe_data = $this->getDataByRule($this->params, $rules);
            $res       = $userModel->edit($safe_data, ['id' => $uid]);
            if ($res !== false) {
                $this->return_msg("00000", "绑定手机号成功", $safe_data);
            } else {
                $this->return_msg("20002", "绑定手机号失败", []);
            }
        }

    }


    /***
     * Desc :获取用户登录信息
     * User : HAIYUN
     * Date : 2022-01-10 14:20
     */
    public function getUserInfo()
    {
        //获取用户
        //根据token获取uid
        $uid = $this->getCurrentTokenVar("uid");
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $uid)->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        $this->return_msg("00000", "获取用户信息成功", $user);
    }

    /***
     * Desc :绑定登录密码
     * User : HAIYUN
     * Date : 2022-01-10 14:50
     */
    public function bindPassword()
    {
        //获取用户
        //根据token获取uid
        $uid = $this->getCurrentTokenVar("uid");
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $uid)->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        //校验参数
        $rules = [
            ['phone_number', 'require|/^1[34578]\d{9}$/', '10001|10002'],
            ['password', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //过滤不必要的参数
        $safe_data = $this->getDataByRule($this->params, $rules);
        //验证用户手机号是否一致
        if ($user['phone_number'] != $safe_data['phone_number']) {
            $this->return_msg("20004", "与绑定手机号不符合", []);
        }
        //修改登录密码
        unset($safe_data['phone_number']);
        //加密登录密码
        $safe_data['password'] = $this->encryptionPassword($safe_data['password']);
        $res                   = $userModel->edit($safe_data, ['id' => $uid]);
        if ($res !== false) {
            $this->return_msg("00000", "绑定登录密码成功", []);
        } else {
            $this->return_msg("20002", "绑定登录密码失败", []);
        }
    }

    /***
     * Desc :加密密码
     * User : HAIYUN
     * Date : 2022-01-10 15:09
     */
    private function encryptionPassword($password)
    {
        //salt 盐
        $salt = config('secure.passowrd_salt');
        return md5($password . $salt);
    }

    /***
     * Desc :手机号密码登录
     * User : HAIYUN
     * Date : 2022-01-10 15:24
     */
    public function LoginByPassword()
    {
        //验证参数
        $rules = [
//            ['code', 'require', '10001'],
            ['phone_number', 'require', '10001'],
            ['password', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //请求微信服务器
        //拿到信息后验证手机号和密码
        $userModel = new UserModel();
        $user      = $userModel->where('phone_number', $this->params['phone_number'])->find();
        if (!$user) {
            $this->return_msg("20004", "未查询到该用户信息", []);
        }
        //比对手机号和密码
        $check_password = $this->encryptionPassword($this->params['password']);
        if ($user['password'] != $check_password) {
            $this->return_msg("20004", "手机号或密码不正确", []);
        }
        //验证通过，生成令牌，返回token.
        //生成令牌,写入缓存
        //key: 令牌
        //value；result,uid
        $result = [
            "openid" => $user['openid'],
        ];
        $cache_value = $this->preparCacheValue($result, $user['id']);
        $token       = $this->saveToCache($cache_value);
        $data        = [
            'token'     => $token,
            'user_info' => $user,
        ];
        $this->return_msg("00000", "登录成功", $data);
    }

    /***
     * Desc:查看其他用户信息
     * User: HAIYUN
     * Date: 2022/4/19 13:22
     */
    public function getUserInfoById() {
        //验证参数
        $rules = [
            ['user_id', 'require', '10001'],
        ];
        $msg   = $this->validate($this->params, $rules);
        if ($msg !== true) $this->return_msg($msg, '参数错误');
        //根据uid查找用户数据，判断是否存在
        $userModel = new UserModel();
        $user      = $userModel->where("id", $this->params['user_id'])->find();
        if (!$user) {
            $this->return_msg("20004", "用户不存在", []);
        }
        $this->return_msg("00000", "获取用户信息成功", $user);
    }

}